// 对资源进行离线缓存 serviceWorker 可以自定义缓存的内容
const CACHE_NAME = "cache_v" + 1; // 版本号
const CACHE_LIST = [
  "/",
  "/index.html",
  "/main.js",
  "/index.css",
  "/api/list",
  "/manifest.json",
  "/icon.png",
];

// 当断网时， 需要拦截请求， 使用缓存的结果
async function fetchAndSave(request) {
  let res = await fetch(request); // 数据流

  let cloneRes = res.clone(); // 为了保证不破坏原有的响应结果
  let cache = await caches.open(CACHE_NAME);
  await cache.put(request, cloneRes); // 用响应结果更新缓存
  return res;
}
// 核心就是拦截请求
self.addEventListener("fetch", (e) => {
  // console.log(e.request.url); // 对请求的路径做拦截
  // serviceWorker 中不支持ajax， 但是支持fetch

  // 如果是静态资源， 不做拦截
  let url = new URL(e.request.url);
  if (url.origin !== self.origin) {
    return;
  }

  // 缓存策略， 更新缓存
  // 缓存优先 cachefirst
  // 仅缓存
  // 网络优先 netfirst
  // 仅网络
  // 从缓存中去， 用网络数据更新缓存
  if (e.request.url.includes("/api")) {
    return e.respondWith(
      fetchAndSave(e.request).catch((err) => {
        return caches.match(e.request);
      })
    );
  }

  // 如果断网， 抛出异常
  // e.respondWith来接收返回的缓存数据
  e.respondWith(
    fetch(e.request).catch((err) => {
      return caches.match(e.request);
    })
  );
});
async function preCache() {
  let cache = await caches.open(CACHE_NAME); // 创建一个缓存空间
  await cache.addAll(CACHE_LIST);
  await self.skipWaiting();
}
// 当serviceWorker 安装时， 需要跳过等待
self.addEventListener("install", (e) => {
  // e.waitUntil表示等待promise执行完成

  //  预先将缓存列表中的数据缓存起来

  e.waitUntil(preCache());
  //   console.log(e);
});

async function clearCache() {
  let keys = await caches.keys();
  return Promise.all(
    keys.map((item) => {
      if (item !== CACHE_NAME) {
        return caches.delete(item);
      }
    })
  );
}
// serviceWorker不是立即生效， 需要在下一次访问的时候才生效
self.addEventListener("activate", (e) => {
  // e.waitUntil(clients.claim());
  e.waitUntil(Promise.all([clearCache(), clients.claim()])); // 重新激活后立即让serviceWorker拥有
});

// workbox => workbox-webpack-plugin
self.addEventListener("push", function (e) {
  // self.registration.showNotification(e.data.text());
  // console.log(e);
  self.registration.showNotification(e.data.text());
});
